package com.ebupt.migu.fineoperationactivitymonitor.media.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ebupt.migu.fineoperationactivitymonitor.common.redis.service.RedisService;
import com.ebupt.migu.fineoperationactivitymonitor.media.mapper.*;
import com.ebupt.migu.mediadata.pojo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tz
 */
@Slf4j
@Service
public class DataBeanToRedis {

    @Resource
    private RedisService redisService;
    @Resource
    private MediaActivityMapper mediaActivityMapper;
    @Resource
    private MediaBannerMapper mediaBannerMapper;
    @Resource
    private MediaBlockMapper mediaBlockMapper;
    @Resource
    private MediaKingMapper mediaKingMapper;
    @Resource
    private MediaRulesMapper mediaRulesMapper;

    public void setRedisCache(){
        //查询进行中的活动
        List<MediaActivity> mediaActivities = mediaActivityMapper.qryByStatus(3);
        Set<Object> block = new HashSet<>();
        Set<Object> banner = new HashSet<>();
        Set<Object> king = new HashSet<>();
        if (null == mediaActivities || mediaActivities.size() < 1){
            log.info("没有可缓存的活动信息");
        } else {
            for (MediaActivity ma : mediaActivities) {
                //构造redis结构
                MediaRedisBean mr = new MediaRedisBean();
                BeanUtils.copyProperties(ma,mr);
                String redisKey = MediaConstants.MEDIA_ACTIVITY_ + mr.getActivityId();
                //判断活动类型
                if (ma.getVisitPoint() == 1) {
                    if (ma.getDisplayType() == 1) {
                        //block
                        mr.setBlocks(getBlockList(ma.getActivityId()));
                        block.add(redisKey);
                    }
                    if (ma.getDisplayType() == 2) {
                        //banner
                        mr.setBanners(getBannerList(ma.getActivityId()));
                        banner.add(redisKey);
                    }
                }
                if (ma.getVisitPoint() == 2) {
                    //金刚区
                    mr.setKings(getKingList(ma.getActivityId()));
                    king.add(redisKey);
                }
                //设置活动详情缓存
                redisService.set(redisKey, JSON.toJSONString(mr));
            }
        }
        // 判断set集合key是否存在，求差集删除过期key
        if (redisService.exists(MediaConstants.MEDIA_BLOCK_ACTIVITIES)){
            Set<Object> hasBlock = redisService.getSet(MediaConstants.MEDIA_BLOCK_ACTIVITIES);
            hasBlock.removeAll(block);
            hasBlock.forEach(e -> redisService.remove_key(e.toString()));
            redisService.setMembersDel(MediaConstants.MEDIA_BLOCK_ACTIVITIES,hasBlock);
        }
        if (redisService.exists(MediaConstants.MEDIA_BANNER_ACTIVITIES)){
            Set<Object> hasBanner = redisService.getSet(MediaConstants.MEDIA_BANNER_ACTIVITIES);
            hasBanner.removeAll(banner);
            hasBanner.forEach(e -> redisService.remove_key(e.toString()));
            redisService.setMembersDel(MediaConstants.MEDIA_BANNER_ACTIVITIES,hasBanner);
        }
        if (redisService.exists(MediaConstants.MEDIA_KING_ACTIVITIES)){
            Set<Object> hasKing = redisService.getSet(MediaConstants.MEDIA_KING_ACTIVITIES);
            hasKing.removeAll(king);
            hasKing.forEach(e -> redisService.remove_key(e.toString()));
            redisService.setMembersDel(MediaConstants.MEDIA_KING_ACTIVITIES,hasKing);
        }
        //更新活动id集合key
        if (block.size() > 0 || banner.size() > 0 || king.size() > 0){
            redisService.setSet(MediaConstants.MEDIA_BLOCK_ACTIVITIES, block);
            redisService.setSet(MediaConstants.MEDIA_BANNER_ACTIVITIES, banner);
            redisService.setSet(MediaConstants.MEDIA_KING_ACTIVITIES, king);
            log.info("融媒活动redis列表更新成功");
        }
    }

    private List<KingBean> getKingList(String activityId){
        List<MediaKing> kings = mediaKingMapper.qryByAid(activityId);
        return kings.stream().filter(e -> isTimeToUse(e.getStartTime(),e.getEndTime())).map(f -> {
            KingBean kb = new KingBean();
            BeanUtils.copyProperties(f,kb);
            kb.setRules(getRuleList(f.getRulesId()));
            return kb;
        }).collect(Collectors.toList());
    }

    private List<BannerBean> getBannerList(String activityId){
        List<MediaBanner> banners = mediaBannerMapper.qryByAid(activityId);
        return banners.stream().filter(e -> isTimeToUse(e.getStartTime(),e.getEndTime())).map(f -> {
            BannerBean bb = new BannerBean();
            BeanUtils.copyProperties(f,bb);
            bb.setRules(getRuleList(f.getRulesId()));
            return bb;
        }).collect(Collectors.toList());
    }

    private List<BlockBean> getBlockList(String activityId){
        List<MediaBlock> blocks = mediaBlockMapper.qryByAid(activityId);
        //先按照block分组
        Map<String, List<MediaBlock>> collect = blocks.stream().collect(Collectors.groupingBy(MediaBlock::getBlockId));
        return collect.values().stream().map(v -> {
            BlockBean bb = new BlockBean();
            BeanUtils.copyProperties(v.get(0),bb);
            bb.setEntries(v.stream().filter(e -> isTimeToUse(e.getStartTime(),e.getEndTime())).map(f -> {
                EntryBean eb = new EntryBean();
                BeanUtils.copyProperties(f,eb);
                eb.setRules(getRuleList(f.getRulesId()));
                return eb;
            }).collect(Collectors.toList()));
            return bb;
        }).collect(Collectors.toList());
    }

    private List<RuleBean> getRuleList(String ruleId){
        List<MediaRules> rules = mediaRulesMapper.qryByRuleId(ruleId);
        return rules.stream().map(e -> {
            RuleBean rb = new RuleBean();
            BeanUtils.copyProperties(e,rb);
            return rb;
        }).collect(Collectors.toList());
    }

    /**
     *  判断当前时间是否能用
     * @param startTime
     * @param endTime
     * @return
     */
    private boolean isTimeToUse(String startTime, String endTime){
        DateTime start = DateUtil.parse(startTime, "yyyy-MM-dd HH:mm:ss");
        DateTime end = DateUtil.parse(endTime, "yyyy-MM-dd HH:mm:ss");
        DateTime now = DateTime.now();
        return now.after(start) && now.before(end);
    }

}
